#你有一段通过下标访问列表或者元组中元素的代码，但是这样有时候会使得你的代码难以阅读，于是你想通过名称来访问元素。
from collections import namedtuple


Subscriber = namedtuple('Subscriber', ['addr', 'phone'])
sub = Subscriber('xx@yy.com', '2016-10-02')
print(sub)

#支持元组的一切操作
addr, phone = sub
print(addr)
print(phone)

Stock = namedtuple('Stock', ['name', 'shares', 'price'])
def compute_cost(records):
    total = 0.0
    for rec in records:
        s = Stock(*rec)
        total += s.shares * s.price
    return total

#命名元组另一个用途就是作为字典的替代，因为字典存储需要更多的内存空间。如
#果你需要构建一个非常大的包含字典的数据结构，那么使用命名元组会更加高效。但
#是需要注意的是，不像字典那样，一个命名元组是不可更改的

s = Stock('ACME', 100, 123.45)
print(s)
#s.shares = 100

#如果你真的需要改变然后的属性，那么可以使用命名元组实例的replace() 方法，
#它会创建一个全新的命名元组并将对应的字段用新的值取代
s = s._replace(shares = 75)
print(s)


#replace() 方法还有一个很有用的特性就是当你的命名元组拥有可选或者缺失字
#段时候，它是一个非常方便的填充数据的方法。你可以先创建一个包含缺省值的原型
#元组，然后使用replace() 方法创建新的值被更新过的实例

Stock2 = namedtuple('Stock2', ['name', 'shares', 'price', 'date', 'time'])
stock_prototype = Stock2('', 0, 0.0, None, None)

def dic_to_stock(d):
    return stock_prototype._replace(**d)

a = {'name': 'ACME', 'shares': 100, 'price': 123.45}
print(dic_to_stock(a))

b = {'name': 'ACME', 'shares': 100, 'price': 123.45, 'date': '02/10/2016'}
print(dic_to_stock(b))
